package com.smart.community.common.realm;


import com.smart.community.common.common.vo.SysOperationVo;
import com.smart.community.common.common.vo.SysRoleVo;
import com.smart.community.common.entity.SysUser;
import com.smart.community.common.service.RoleService;
import com.smart.community.common.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 子未语
 */
public class UserRealm extends AuthorizingRealm {
    @Resource
    private SysUserService sysUserService;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //用户输入的用户名
        String username = (String) token.getPrincipal();
        SysUser userInfo = sysUserService.getUserInfo(username);
        if (ObjectUtils.isEmpty(userInfo)) {
            throw new UnknownAccountException();
        }
        if (userInfo.getDelStatus() != 0) {
            throw new LockedAccountException();
        }
        return new SimpleAuthenticationInfo(userInfo, userInfo.getLoginPassword(), null, username);
    }


    @Resource
    private RoleService roleService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取认证用户对象
        SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();
        List<SysRoleVo> sysRoleVos = roleService.queryRoles(sysUser.getSysUserId());
//        stream流
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //添加角色数据
        authorizationInfo.setRoles(sysRoleVos.stream().map(SysRoleVo::getRoleName).collect(Collectors.toSet()));
        //添加权限数据
        authorizationInfo.setStringPermissions(sysRoleVos.stream().flatMap(
                sysRoleVo -> sysRoleVo.getOperationList().stream().map(SysOperationVo::getOperationName)
        ).collect(Collectors.toSet()));
        return authorizationInfo;
    }
}
